﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Drawing;
using RH.Common.Storage;
using RH.Common.Extensions;


namespace RH.Web.Utility
{
    public static class ImageManager
    {
        private static readonly string _ProductImagePath = HttpContext.Current.Server.MapPath(AppConstants.Directories.PRODUCT_IMAGES);
        private static readonly string _CompanyLogoPath = HttpContext.Current.Server.MapPath(AppConstants.Directories.COMPANY_LOGO);
        private static readonly string _TempPath = HttpContext.Current.Server.MapPath(AppConstants.Directories.TEMP);

        public static void DeleteProductImages(string filename)
        {
            String fullPath = Path.Combine(_ProductImagePath, filename);
            if(File.Exists(fullPath))
                File.Delete(fullPath);

            ///Delete the Thumb
            String thumbFileName = String.Format("{0}_Thumb{1}", Path.GetFileNameWithoutExtension(filename), Path.GetExtension(filename));
            fullPath = Path.Combine(_ProductImagePath, thumbFileName);
            if (File.Exists(fullPath))
                File.Delete(fullPath);
        }

        /// <summary>
        /// Saves a Thumbnail from the Source filename
        /// </summary>
        /// <param name="sourceFilename">Full path to the Source file</param>
        /// <param name="proposedDestinationFileName">This is the Destination file name. Give null if you want to automatically choose from the Source file name.</param>
        /// <param name="rectangle"></param>
        /// <param name="folderID"></param>
        /// <param name="deleteSourceFile"></param>
        /// <param name="imageType"></param>
        /// <returns>Returns an Array of Filenames. In Index 0 it contains the original file name and the index 1 contains the thumbnail file</returns>
        public static String[] SaveThumbnail(String sourceFilename, String proposedDestinationFileName, Rectangle rectangle, int folderID, bool deleteSourceFile, ImageFor imageType)
        {
            using (var image = Image.FromFile(sourceFilename))
            {                
                var img = Imaging.Crop(image, rectangle);
                Image thumbImage = Imaging.Resize(img, _GetThumbWidth(imageType)); //Imaging.Resize(img, 200, 150, true);
                //var small = Imaging.Resize(img, 100, 75, true);
                //var mini = Imaging.Resize(img, 45, 34, true);
                String thumbFileName = String.Empty;
                if (imageType == ImageFor.Product)
                    thumbFileName = String.Format("{0}/{1}", _ProductImagePath, folderID);
                else
                    thumbFileName = String.Format("{0}/{1}", _CompanyLogoPath, folderID);

                if(!Directory.Exists(thumbFileName))
                    Directory.CreateDirectory(thumbFileName);

                //Make the resulting filename Unique in the that directory
                String uniqueDestinationFileName = proposedDestinationFileName;
                if(uniqueDestinationFileName.IsNullOrEmpty())
                    uniqueDestinationFileName = GetNextFileName(sourceFilename);

                thumbFileName = Path.Combine(thumbFileName, String.Format("{0}_Thumb.jpg", Path.GetFileNameWithoutExtension(uniqueDestinationFileName)));
                //Save the Thumbnail
                Imaging.SaveJpeg(thumbFileName, thumbImage);
                thumbImage.Dispose();
                //img.Dispose();
                image.Dispose();
                
                ///Move the Original Image
                
                //MoveFile(sourceFilename, Path.Combine((requestFrom == "ProductImage") ? _ProductImagePath : _CompanyLogoPath, String.Format("{0}.jpg", imageID)));
                String destinationFile = Path.Combine(Path.GetDirectoryName(thumbFileName), uniqueDestinationFileName);                
                //MoveFile(sourceFilename, destinationFile);

                if (deleteSourceFile)
                {
                    File.Delete(sourceFilename);
                    //img.Dispose();
                }                
                Imaging.SaveJpeg(destinationFile, img);
                img.Dispose();

                return new String[] {destinationFile, thumbFileName};
            }
        }

        private static int _GetThumbWidth(ImageFor imageType)
        {
            if (imageType == ImageFor.Product)
                return ConfigReader.ProductThumbWidth;

            return 200;
        }
        /// <summary>
        /// Moves a Given file to a destination. Overrites existing file.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        public static void MoveFile(String source, String destination)
        {
            if (File.Exists(source))
            {
                File.Move(source, destination);
            }
        }

        public static void DeleteCompanyLogo(String fileName, int companryID)
        {
            if (!fileName.IsNullOrEmpty() && companryID > 0)
            {
                String logoPath = GetCompanyLogoUrl(fileName, companryID);
                logoPath = HttpContext.Current.Server.MapPath(logoPath);
                
                if (File.Exists(logoPath))
                {
                    File.Delete(logoPath);
                }
            }
        }

        public static string SaveTempJpeg(Stream inputStream, float aspectRatio, out int w, out int h)
        {
            var g = Guid.NewGuid() + ".jpg";
            if (!Directory.Exists(_TempPath))
                Directory.CreateDirectory(_TempPath);

            var filePath = Path.Combine(_TempPath, g);

            using (var image = Image.FromStream(inputStream))
            {
                int newWidth = 533;
                //int calculatedHeight = (int)(((float) calculatedWidth) / aspectRatio);
                Image resized = Imaging.Resize(image, newWidth);
                Imaging.SaveJpeg(filePath, resized);                
                w = resized.Width;
                h = resized.Height;
                resized.Dispose();
                image.Dispose();
                return g;
            }
        }
        /// <summary>
        /// Gets the Tempurary Image Url
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static String GetTempImageUrl(string fileName)
        {
            return String.Format("{0}/{1}", AppConstants.Directories.TEMP, fileName);
        }
        /// <summary>
        /// Gets the ProductImageUrl
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static String GetProductImageUrl(String fileName, int productID)
        {
            if (fileName.IsNullOrEmpty())
                return String.Format("{0}/{1}", AppConstants.Directories.IMAGES, AppConstants.UI.NO_IMAGE);

            return String.Format("{0}/{1}/{2}", AppConstants.Directories.PRODUCT_IMAGES, productID, fileName);
        }
        /// <summary>
        /// Gets the LogoUrl
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static String GetCompanyLogoUrl(string fileName, int companyID)
        {
            if(fileName.IsNullOrEmpty())
                return String.Format("{0}/{1}", AppConstants.Directories.IMAGES, AppConstants.UI.NO_LOGO);       

            return String.Format("{0}/{1}/{2}", AppConstants.Directories.COMPANY_LOGO, companyID, fileName);
        }

        /// <summary>
        /// Generates Chrome like Unique File name depending on the User given file name in the corresponding directory
        /// </summary>
        /// <param name="fileName">File name must be given with the fully qualified directory path</param>
        /// <returns>A unique file name. Does not include directory path with the file name.</returns>
        public static String GetNextFileName(String fileName)
        {
            if (!File.Exists(fileName))
                return System.IO.Path.GetFileName(fileName);

            String fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName).Trim();
            if (fileNameWithoutExtension.EndsWith(")"))
            {
                if (fileNameWithoutExtension.IndexOf("(") > -1)
                {
                    int startIndex = fileNameWithoutExtension.LastIndexOf('(') + 1;
                    int length = (fileNameWithoutExtension.LastIndexOf(')') - startIndex);
                    String str = fileNameWithoutExtension.Substring(startIndex, length);
                    int fileIndex = str.ToInt();
                    String newFileName = fileNameWithoutExtension.Substring(0, fileNameWithoutExtension.LastIndexOf('('));
                    newFileName = String.Format("{0}({1}){2}",
                        newFileName,
                        fileIndex + 1,
                        Path.GetExtension(fileName)
                    );
                    return GetNextFileName(Path.Combine(Path.GetDirectoryName(fileName), newFileName));
                }
            }
            String proposedFileName = String.Format("{0}({1}){2}", fileNameWithoutExtension, 1, Path.GetExtension(fileName));
            proposedFileName = Path.Combine(Path.GetDirectoryName(fileName), proposedFileName);
            return GetNextFileName(proposedFileName);
        }
    }

    public enum ImageFor
    {
        Product,
        CompanyLogo
    }
}